// 这里的 loader-utils 是 v2 版本，与 v3 API 有一些差异
// https://github.com/webpack/loader-utils/tree/v2.0.0?tab=readme-ov-file#getoptions
import { getOptions } from 'loader-utils';
// 用于校验 loader 的配置
// https://www.npmjs.com/package/schema-utils
// https://github.com/webpack/schema-utils
import { validate } from 'schema-utils';

import schema from './options.json';

export default function rawLoader(source) {
  // 获取 loader 的配置
  // 这里的 this 是 loader 的上下文，webpack 在运行时会注入
  // https://github.com/webpack/loader-utils/tree/v2.0.0?tab=readme-ov-file#getoptions
  const options = getOptions(this);

  // schema 内容:
  // {
  //   "additionalProperties": false,
  //   "properties": {
  //     "esModule": {
  //       "type": "boolean"
  //     }
  //   },
  //   "type": "object"
  // }
  validate(schema, options, {
    // 用于错误提示的 loader 名称
    name: 'Raw Loader',
    // 用于错误提示的路径
    baseDataPath: 'options',
  });

  // 这里将 source 这个字符串转成 JSON 字符串，同时处理了换行符
  // 不然 export default 拼接字符串后可能会出现语法不正确的情况
  const json = JSON.stringify(source)
    // 换行符
    .replace(/\u2028/g, '\\u2028')
    // 段落分隔符
    .replace(/\u2029/g, '\\u2029');

  // 根据 options 中的 esModule 字段来决定是否输出 ESM 代码
  const esModule =
    typeof options.esModule !== 'undefined' ? options.esModule : true;

  // 如果是 ESM 输出 `export default = ${json}`
  // 如果是 CJS 输出 `module.exports = ${json}`
  return `${esModule ? 'export default' : 'module.exports ='} ${json};`;
}
